<?php
/**
 * RAI(Remote Access Interface) Bencode格式定义类
 *
 *
 * @author iwind <iwind.iwind@gmail.com>
 * @link http://www.4kiki.net/
 * @version $Id: RaiBencodeFormat.php 312 2008-04-23 16:29:38Z iwind $
 * @package net.4kiki.rai.format
 */


import("net.4kiki.rai.format.bencode.*");

/**
 * RAI Bencode 数据格式
 * 
 * 注意: 使用bencode格式传输数据时，将有信息的缺失（比如将double型强转为integer型）.
 *
 * @version $Id: RaiBencodeFormat.php 312 2008-04-23 16:29:38Z iwind $
 * @package net.4kiki.rai.format
 * @since 0.0.3
 */
class RaiBencodeFormat implements RaiFormat {
	private $charset;
	
	/**
	 * 构造器
	 *
	 * @param string $charset 字符集
	 */
	public function __construct($charset = "UTF-8") {
		$this->charset = $charset;
	}
	
	/**
	 * 解码请求数据为对象
	 *
	 * @param string $data 请求数据
	 * @return RaiRequest
	 */
	public function decodeRequest($data) {
		$decoder = new File_Bittorrent2_Decode();
		$array = $decoder->decode($data);
		if (!is_array($array) || !isset($array["serviceName"]) || !isset($array["methodName"]) || !isset($array["arguments"])) {
			throw new RaiException("invalid request '" . print_r($array, true) . "'");
		}
		$request = new RaiRequest($array["serviceName"], $array["methodName"], $array["arguments"]);
		return $request;
	}
	
	/**
	 * 编码请求对象为字符串
	 *
	 * @param RaiRequest $request 请求对象
	 * @return string
	 */
	public function encodeRequest(RaiRequest $request) {
		$encoder = new File_Bittorrent2_Encode();
		$array = array(
						"serviceName"=>$request->getServiceName(), 
						"methodName"=>$request->getMethodName(),
						"arguments"=>$request->getArguments()
					);
		return $encoder->encode($array);
	}
	
	/**
	 * 解码响应数据为对象
	 *
	 * @param string $data 响应数据
	 * @return RaiResponse
	 */
	public function decodeResponse($data) {
		$decoder = new File_Bittorrent2_Decode($data);
		$array = $decoder->decode($data);
		if (!is_array($array)) {
			throw new RaiException("invalid response '" . $data . "'");
		}
		if (!array_key_exists("code", $array) || !array_key_exists("data", $array) || !array_key_exists("message", $array)) {
			throw new RaiException("invalid response");
		}
		$response = new RaiResponse($array["code"], $array["message"], $array["data"]);
		if (isset($array["fault"])) {
			$fault = $array["fault"];
			if (is_array($fault) && isset($fault["code"]) && isset($fault["message"])) {
				$response->setFault(new RaiFault($fault["code"], $fault["message"]));
			}
			else {
				throw new RaiException("invalid fault in response");
			}
		}
		return $response;
	}
	
	/**
	 * 编码响应对象为字符串
	 *
	 * @param RaiResponse $response 响应对象
	 * @return string
	 */
	public function encodeResponse(RaiResponse $response) {
		$encoder = new File_Bittorrent2_Encode();
		$array =  array(
						"code"=>$response->getCode(),
						"data"=>$response->getData(),
						"message"=>$response->getMessage(),
					);
		$fault = $response->getFault();
		if ($fault != null) {
			$array["fault"] = array(
								"code"=>$response->getFault()->getCode(),
								"message"=>$response->getFault()->getMessage()
							);
		}
		return $encoder->encode($array);	
	}
	
	/**
	 * 取得内容类型
	 *
	 * @return string
	 */
	public function getContentType() {
		return "text/plain;charset=" . $this->charset;
	}
}

?>